import { _decorator, Component, Node, Animation, Label, ProgressBar, AnimationClip, Color, Sprite } from 'cc';
import { ConfigKey, AppControll, level_monster_Refresh_config, EventName, configKey, PopView } from '../../manager/AppControll';
import { DataHelper } from '../../system/DataHelper';
import { GameState, FightControl, GameModel } from '../FightControl';
import { MainGun } from '../gun/MainGun';
import { SecondaryGuns } from '../gun/SecondaryGuns';
import { LevelMonsterManager } from './LevelMonsterManager';
import EvtManger from '../../tools/EvtManger';
import { PopManager } from '../../manager/PopManager';
import { Loader } from '../../tools/LoadManger';
import { GameData } from '../../system/GameData';
import { LevelChallengeResult, LevelResult } from '../../pop/LevelChallengeResult';
import { levelData } from '../../pop/Rank';
import { SoundManager } from '../../manager/SoundManger';
import { MonsterManager } from '../monster/MonsterManager';

const { ccclass, property } = _decorator;

@ccclass('levelModel')
export class levelModel extends Component {
    private firstLevel: number = 10000;
    private mLevelChange: Node = null;
    private mCurLevel: number = 0;
    private mLevelModelConfig: level_monster_Refresh_config = null;
    private mMonsterManager: LevelMonsterManager = null;
    private mNdStage: Node = null;
    private mNdExit: Node = null;
    private mNdlevelChallenge: Node = null;
    private mNdPortal: Node = null;
    private mMonster: Node = null;
    private mMainGun: MainGun = null;
    private mNdSecondaryGuns: SecondaryGuns = null;
    private mNdCurDeathMonster: number = 0;
    private mRemainingHP = 0;
    private mCurTime = 0;
    private isStart: boolean = false;
    private mLbTime: Label = null;
    private mNdGift: Node = null; //改节点动画结束事件已再fightView注册
    private mNdBg: Node = null;
    private mMaxLevelData: levelData = null;
    private mlevelChallengeBtn: Node = null;
    private mCurFinishTime = 0;
    private mCurFinishLevel = 0;
    protected onLoad(): void {
        this.mLevelChange = this.node.getChildByName("levelChange");
        this.mMonster = this.node.getChildByName("fightView").getChildByName("monsterPoint");
        this.mMonsterManager = new LevelMonsterManager(this.mMonster);
        this.mNdStage = this.node.getChildByName("stage");
        this.mNdlevelChallenge = this.node.getChildByName("levelChallenge");
        this.mLbTime = this.mNdlevelChallenge.getChildByName("time").getChildByName("times").getComponent(Label);
        this.mNdPortal = this.node.getChildByName("fightView").getChildByName("portal");
        this.mNdExit = this.node.getChildByName("exit");
        this.mMainGun = this.node.getChildByName("fightView").getChildByName("mainGun").getComponent(MainGun);
        this.mNdSecondaryGuns = this.node.getChildByName("fightView").getChildByName("secondGuns").getComponent(SecondaryGuns);
        this.mNdExit.on(Node.EventType.TOUCH_END, this.OnExit, this);
        this.mNdGift = this.node.getChildByName("gift");
        this.mNdBg = this.node.getChildByName("fightView").getChildByName("bg_level");
        this.mlevelChallengeBtn = this.node.getChildByName("levelChallengeBtn");
        AppControll.Platform.GetMyLevelR((mylevel) => {
            GameData.myLevelData = mylevel;
        })
        this.GetMaxLevelData();
        this.InitPortal();
        this.RegisteredEvent();
    }

    GetMaxLevelData() {
        AppControll.Platform.GetMyLevelR((mLevelData) => {
            this.mMaxLevelData = mLevelData
        })
    }

    InitPortal() {
        let an = this.mNdPortal.getChildByName("portalImg").getComponent(Animation);
        Loader.DynamicBgLoadDir("Portal", (arr) => {
            const clip = AnimationClip.createWithSpriteFrames(arr, 10);
            clip.name = "Portal";
            clip.wrapMode = AnimationClip.WrapMode.Loop;
            an.addClip(clip);
        })
    }

    RegisteredEvent() {
        EvtManger.on(EventName.levelModeMoveFinish, this, this.OnMoveFinish);
        EvtManger.on(EventName.monsterDeath, this, this.MonsterDeath);
        EvtManger.on(EventName.exitLevel, this, this.ShowResult);
        EvtManger.on(EventName.doExitLevel, this, this.ExitLevel);
        EvtManger.on(EventName.levelGift, this, this.ShowGift);
        this.mLevelChange.getComponent(Animation).on(Animation.EventType.FINISHED, this.DoChangeLevel, this)
    }

    DoChangeLevel() {
        this.isStart = true;
        this.mMonsterManager.StartLevel(this.mLevelModelConfig)
    }

    ShowGift() {
        this.mNdGift.active = true;
        this.mNdGift.getComponent(Animation).play();
    }

    OnMoveFinish(hp: number) {
        if (!this.isStart) return;
        this.mRemainingHP -= hp;
        if (this.mRemainingHP > 0) {
            let an = this.mNdPortal.getChildByName("portalImg").getComponent(Animation);
            an.getComponent(Sprite).color = new Color(10, 255, 255, 255);
            this.scheduleOnce(() => {
                an.getComponent(Sprite).color = new Color(255, 255, 255, 255);
            }, 0.1);
            this.UpdataPortal(this.mRemainingHP / Number.parseInt(DataHelper.GetConfigByKey(ConfigKey.levelHp).value))
        } else {
            this.isStart = false;
            this.UpdataPortal(0);
            this.ShowResult();
        }
    }

    UpdataPortal(num: number) {
        this.mNdPortal.getChildByName("ProgressBar").getComponent(ProgressBar).progress = num;
    }

    UpdatelevelChallenge() {
        this.mNdlevelChallenge.active = true;
        let lbCur = this.mNdlevelChallenge.getChildByName("ProgressBar").getChildByName("Bar").getChildByName("biaoji").getChildByName("current").getComponent(Label);
        let lbMax = this.mNdlevelChallenge.getChildByName("maxLevelBg").getChildByName("maxLevel").getComponent(Label);
        let progress = this.mNdlevelChallenge.getChildByName("ProgressBar").getComponent(ProgressBar)
        let length = Object.keys(DataHelper.GetLevelModelRefresh()).length;
        lbMax.string = length + "";
        lbCur.string = this.mCurLevel + "";
        progress.progress = this.mCurLevel / length;
    }

    MonsterDeath() {
        if (!this.isStart) return;
        if (FightControl.gamemodel != GameModel.levelModel) return;
        if (this.mLevelModelConfig == null) return
        this.mNdCurDeathMonster++;
        if (this.mNdCurDeathMonster >= this.mLevelModelConfig.maxMonster) {
            if (this.mCurLevel == Object.keys(DataHelper.GetLevelModelRefresh()).length) {
                this.isStart = false;
                this.mCurFinishTime = this.mCurTime;
                this.mCurFinishLevel = this.mCurLevel
                this.ShowResult();
                return;
            }
            this.mCurLevel++;
            FightControl.nCurLevel = this.mCurLevel;
            this.mNdCurDeathMonster = 0;
            this.isStart = false;
            this.ChangeLevel();
        }
    }

    OnExit() {
        SoundManager.Instance<SoundManager>().PlayEffect(GameData.btnClick);
        PopManager.Instance<PopManager>().ShowPop(PopView.exitGame);
    }

    ExitLevel() {
        this.UpdateLevelR();
        this.isStart = false;
        this.mlevelChallengeBtn.active = true;
        this.mNdPortal.getChildByName("portalImg").getComponent(Animation).stop();
        this.mNdGift.active = false;
        this.mNdBg.active = false;
        this.mNdGift.getComponent(Animation).stop();
        this.mNdStage.active = true;
        this.mNdlevelChallenge.active = false;
        this.mLevelChange.active = false;
        this.mLevelModelConfig = DataHelper.GetLevelModelRefreshById(this.mCurLevel + this.firstLevel);
        this.mNdExit.active = false;
        this.mNdPortal.active = false;
        this.mNdBg.active = false;
        this.mMonsterManager.ChangeLevelMode();
        LevelMonsterManager.ltMonster.forEach(nd => {
            MonsterManager.normalMonsterPool.put(nd);
        })
        LevelMonsterManager.ltMonster = [];
        MonsterManager.ltMonster = [];
        EvtManger.do(EventName.normalChanllenge);

    }

    UpdateLevelR() {
        if (this.mMaxLevelData) {
            if (this.mCurLevel > this.mMaxLevelData.level) {
                AppControll.Platform.UpdateLevelR(this.mCurFinishLevel, this.mCurFinishTime);
            } else if (this.mCurLevel == this.mMaxLevelData.level && this.mCurTime <= this.mMaxLevelData.time) {
                AppControll.Platform.UpdateLevelR(this.mCurFinishLevel, this.mCurFinishTime);
            }
        } else {
            AppControll.Platform.UpdateLevelR(this.mCurFinishLevel, this.mCurFinishTime);
        }
    }

    StartLevelMode() {
        this.mRemainingHP = Number.parseInt(DataHelper.GetConfigByKey(ConfigKey.levelHp).value);
        this.mNdStage.active = false;
        this.mlevelChallengeBtn.active = false;
        this.mLevelChange.active = true;
        this.mCurLevel = 1;
        FightControl.nCurLevel = this.mCurLevel;
        this.mCurTime = 0;
        this.mNdCurDeathMonster = 0;
        this.mLevelModelConfig = DataHelper.GetLevelModelRefreshById(this.mCurLevel + this.firstLevel);
        this.mNdExit.active = true;
        this.mNdPortal.active = true
        this.ChangeLevel();
        this.UpdataPortal(this.mRemainingHP / Number.parseInt(DataHelper.GetConfigByKey(ConfigKey.levelHp).value))
        this.mNdBg.active = true;
        this.mNdPortal.getChildByName("portalImg").getComponent(Animation).play("Portal");
    }

    ChangeLevel() {
        this.UpdateLevelR();
        this.GetMaxLevelData();
        this.mLevelModelConfig = DataHelper.GetLevelModelRefreshById(this.mCurLevel + this.firstLevel);
        this.mLevelChange.getComponent(Animation).play();
        let ndLbList = this.mLevelChange.getChildByName("staget").getChildByName("bg").getChildByName("labelList");
        let lbStageNum = ndLbList.getChildByName("stageNum").getComponent(Label);
        let lbMonsterHp = ndLbList.getChildByName("monsterHp").getComponent(Label);
        lbStageNum.string = "第" + (this.mLevelModelConfig.stageID - this.firstLevel) + "关";
        lbMonsterHp.string = this.mLevelModelConfig.stageAverageHp + "";
        this.mCurFinishTime = this.mCurTime;
        this.mCurFinishLevel = this.mCurLevel - 1;
        this.UpdatelevelChallenge()
    }

    protected update(dt: number): void {
        if (FightControl.gamemodel == GameModel.normal) return;
        if (GameData.isPause) return;
        if (!this.isStart) return;
        this.mCurTime += dt;
        this.mLbTime.string = this.mCurTime.toFixed(1);
        this.mMonsterManager.Tick(dt);
        if (this.mMainGun) {
            this.mMainGun.Tick(dt)
        }
        if (this.mNdSecondaryGuns) {
            this.mNdSecondaryGuns.Tick(dt);
        }
    }

    ShowResult() {
        GameData.isPause = true;
        let levelData: levelData = {
            _id: GameData.openId,
            headImg: "",
            level: this.mCurFinishLevel,
            time: this.mCurFinishTime,
            nickName: "",
        }
        if (GameData.userInfo) {
            levelData.headImg = GameData.userInfo.avatarUrl;
            levelData.nickName = GameData.userInfo.nickName
        }
        GameData.myLevelData = levelData;
        PopManager.Instance<PopManager>().ShowPop(PopView.levelChallengeResult, (nd) => {
            let result: LevelResult = {
                level: this.mCurFinishLevel,
                time: this.mCurFinishTime
            }
            let maxResult: LevelResult = {
                level: 0,
                time: 0
            }
            if (!this.mMaxLevelData) {
                maxResult = result;
            } else {
                maxResult = this.mMaxLevelData;
                if (this.mMaxLevelData.level < result.level) maxResult = result;
                if (this.mMaxLevelData.level == result.level && this.mMaxLevelData.time > result.level) maxResult = result;
            }
            nd.getComponent(LevelChallengeResult).InitData(result, maxResult);
        });
    }

}


